Skip to content

fix(models): accept opus-4.8 and hoist inline system messages - #246

Open
sour2001 wants to merge 1 commit into
jwadow:mainfrom
sour2001:fix/opus-4.8-and-inline-system-messages
Open

fix(models): accept opus-4.8 and hoist inline system messages#246
sour2001 wants to merge 1 commit into
jwadow:mainfrom
sour2001:fix/opus-4.8-and-inline-system-messages

Conversation

@sour2001

@sour2001 sour2001 commented Jul 9, 2026

Copy link
Copy Markdown

What & Why

Two related fixes so claude-opus-4.8 works end-to-end through the gateway. Both surfaced as 422 errors when pointing a client (Claude Code) at the Anthropic endpoint.

1. Add claude-opus-4.8 to FALLBACK_MODELS

The fallback model list topped out at claude-opus-4.7. When Kiro's /ListAvailableModels doesn't return 4.8 (or the gateway falls back to the static list), the resolver treated it as an unknown pass-through model, which Kiro then rejected. Added the ID so it resolves from cache like the other current models. The name normalizer already handles the common input shapes (claude-opus-4-8, claude-4.8-opus-high, date suffixes) — they all map to claude-opus-4.8.

2. Hoist inline role: "system" messages

Anthropic's schema only accepts user/assistant inside the messages array; the system prompt belongs in the top-level system field. Some clients (Claude Code, LangChain, OpenAI-style callers) inline role: "system" messages instead, which failed with:

422 literal_error: Input should be 'user' or 'assistant' ... input: "system"

Added a mode="before" validator on AnthropicMessagesRequest and AnthropicCountTokensRequest that moves inline system messages into the top-level system field before per-message validation runs. It:

  • Merges with an existing top-level system (string or list-of-blocks form) rather than clobbering it
  • Joins multiple inline system messages in order
  • Handles system content given as a string or as a list of text blocks
  • Strips empty inline system messages (which would otherwise still 422)
  • Is a no-op when there are no inline system messages

Applied to both request models for consistency (messages + count_tokens).

Test coverage

All new tests follow the existing Arrange-Act-Assert + print-diagnostics style.

  • tests/unit/test_models_anthropic.py::TestInlineSystemMessageHoisting — 10 tests: single/multiple inline system messages, merge with existing string/list system, block-form content, empty content, count_tokens endpoint, and typed-object passthrough.
  • tests/unit/test_config.py::TestFallbackModelsIntegration::test_opus_4_8_present_and_resolves — verifies claude-opus-4.8 is in the list and resolves from cache for both dot and dash client formats.

Full suite: 1702 passed.

- Add claude-opus-4.8 to FALLBACK_MODELS so requests resolve from cache
  instead of being rejected as unknown pass-through models.
- Hoist inline 'role: system' messages into the top-level system field
  in AnthropicMessagesRequest and AnthropicCountTokensRequest. Fixes 422
  "Input should be 'user' or 'assistant'" from clients (Claude Code,
  LangChain, OpenAI-style callers) that inline the system prompt in the
  messages array.
- Add comprehensive tests for both changes (edge cases: multiple system
  messages, merge with existing string/list system, block content, empty
  content, count_tokens endpoint).
@cla-bot

cla-bot Bot commented Jul 9, 2026

Copy link
Copy Markdown

Thanks for the PR! 🎉

Before merge, we need a one-time CLA confirmation.
It confirms that you have the right to contribute this code and allow the project to use it.

Full CLA text:
https://github.com/jwadow/kiro-gateway/blob/main/CLA.md

Please reply once with:

I have read the CLA and I accept its terms

You need to write once, all further messages from me can be ignored.

@sour2001

sour2001 commented Jul 9, 2026

Copy link
Copy Markdown
Author

I have read the CLA and I accept its terms

@musa-2066462 musa-2066462 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just tested this code locally and it works perfectly.
U just need to change the anthropic model to this :
export ANTHROPIC_MODEL="claude-opus-4-8-20260528"

@ankitcharolia

Copy link
Copy Markdown

@sour2001 @musa-2066462 could you give a try to this gateway: https://github.com/ankitcharolia/kiro-gateway

It supports all necessary endpoints for OpenAI and Anthropic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants